#include <array>
#include <iostream>
#include <vector>
#include <thread>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <map>
#include <set>
#include <string.h>
#include <unordered_map>

using namespace std;
// TIP To <b>Run</b> code, press <shortcut actionId="Run"/> or
// click the <icon src="AllIcons.Actions.Execute"/> icon in the gutter.
int main1() {
    // TIP Press <shortcut actionId="RenameElement"/> when your caret is at the
    // <b>lang</b> variable name to see how CLion can help you rename it.
    auto lang = "C++";
    std::cout << "Hello and welcome to " << lang << "!\n";

    for (int i = 1; i <= 5; i++) {
        // TIP Press <shortcut actionId="Debug"/> to start debugging your code.
        // We have set one <icon src="AllIcons.Debugger.Db_set_breakpoint"/>
        // breakpoint for you, but you can always add more by pressing
        // <shortcut actionId="ToggleLineBreakpoint"/>.
        std::cout << "i = " << i << std::endl;
    }

    return 0;
}


int main2() {
    int age = 100;
    char c = 'c';
    std::cout << "res " << age << std::endl;
    printf("asa %d", 1117736);

    std::string s = "hello";
    std::vector<int> v = {1, 2, 3, 4, 5};
    std::array<int,5> vv= {1, 2, 3, 4, 5};

    typedef int distance;
    distance aa = 100;

    enum people {huang,kong,liu} p;
    p = huang;
    p = kong;
    std::cout << "--"<< p << "---"<< std::endl;
    std::cout <<  p << std::endl;

    return  0;
}
// TIP See CLion help at <a
// href="https://www.jetbrains.com/help/clion/">jetbrains.com/help/clion/</a>.
//  Also, you can try interactive lessons for CLion by selecting
//  'Help | Learn IDE Features' from the main menu.

int count ;

extern void write_extern();


thread_local int thread_local_var ;

void thread_local_fun(int value,int t_id) {
    while (value-- > 0) {
        std::cout << "thread_local t_id "<< t_id <<  "value is " << value << std::endl;
    }

}

void test_thread_local() {
    thread t1(thread_local_fun, 1,1);
    thread t2(thread_local_fun, 2,2);
    t1.join();
    t2.join();
}

void test_sm() {
    int num = 10;
    int res ;
    res = num++;
    std::cout << "res is " << res << std::endl;
    std::cout << "num is " << num << std::endl;

    num = 10;
    res = num--;
    std::cout << "res is " << res << std::endl;
    std::cout << "num is " << num << std::endl;
}

void test_cal() {
    int a= 100;
    int b ;

    b= a+= 1;
    std::cout << "b is " << b << std::endl;

}


void test_sizeof() {
    int a = 100;
    char b = 'b';
    std::string c = "hello111";
    std::cout << sizeof(a) << std::endl;
    std::cout << sizeof(b) << std::endl;
    std::cout << sizeof(c) << std::endl;
}


int max(int num1,int num2){
    short num3 =1000;
    int num4 = abs(num3);
    return num1 >num2 ?num1:num2;
}

int gen_random() {
    srand(time(nullptr));
    return rand();
}

thread gen_thread(int num) {
    thread temp_t(thread_local_fun, num,num);
    return temp_t;
}

void test_vector_thread() {
    vector<thread> thread_list;
    for (int i = 0; i < 10; i++) {
        int num = gen_random();
        std::cout << "num is " << num << std::endl;
        thread_list.push_back(gen_thread(num));
    };
    for (int i = 0; i < 10; i++) {
        thread_list[i].join();
    }
}

void test_vector_thread2() {
    thread thread_list[10];
    for (int i = 0; i < 10; i++) {
        int num = gen_random();
        std::cout << "num is " << num << std::endl;
        thread_list[i] = gen_thread(num);
    };
    for (int i = 0; i < 10; i++) {
        thread_list[i].join();
    }
}

void test_str() {
    char name[] = "c++";
    char name2[] = "as";;
    strcpy(name2, "hello");
    strcat(name2,name);
    bool res = strcmp(name2,name);
    std::cout << "res is " << res << std::endl;
    int length = strlen(name);
    std::cout << "length is " << length << std::endl;

    // char* a = strchr(name2,'a');
    // std::cout << "a is " << a << std::endl;

    // char* index = strstr(name2,"a");
    // std::cout << "index is " << index << std::endl;


    string nickname = "hello cpp!";
    std::cout << "nickname is " << nickname << std::endl;
    length = nickname.length();
    std::cout << "length is " << length << std::endl;

    cout << "nickname addr is " << &nickname << std::endl;
    string *ip = &nickname;

    cout << "nickname value is " << *ip << std::endl;

}

int testptr() {
    int *ptt = nullptr;
    int *pt_p = nullptr;
    cout << "ptt is " << ptt << std::endl;


    int nums[] = {1,2,3,4,5};
    int *num_pt = &nums[0];
    int *num_pt_p = nums;
    cout << "num_pt is " << num_pt << std::endl;
    cout << "num_pt_p is " << num_pt_p << std::endl;

    int length =5;

    int *temp = nullptr;
    for (int i = 0; i < length; i++) {
        num_pt++;
        cout << "----------------------------" << std::endl;
        cout << "index is " << i << std::endl;
        cout << "num_pt is " << num_pt << std::endl;
        cout << "num_pt_p is " << &nums[i+1] << std::endl;
        temp = &nums[i+1];
        cout << "temp is " << *temp << std::endl;

    }


    int a = 0x61fdb8;
    int b = 0x61fdbc;
    int c = b -a;
    cout << "a = " << c << std::endl;

    int  var[3] = {10, 100, 200};

    for (int i = 0; i < 3; i++)
    {
        // *var = i;    // 这是正确的语法
        *(var+i) = i;
        // var++;       // 这是不正确的
    }
    for (int value:var) {
        cout << "value is " << value << std::endl;
    }

    int arr1[] = {1, 2, 3, 4};
    int arr2[] = {112, 2, 2};
    int *num_li[2] = {arr1, arr2};
    int *num_li2[2] = {
        new int[4]{12,1,2,32},
        new int[4]{12,1,2,32},
    };

    // char *name_li[] =  {
    //     "hello1",
    //     "hello2",
    //     "hello3",
    //     "hello4",
    // };
    //
    // for (char* name: name_li) {
    //     cout << "name is " << name << std::endl;
    // }

    return 0;
}



void test_array_ptr() {
    /*
     *  name_li 中的每个元素，是一个char 类型的指针。
     *  string 相当于一个 char 数组。
     *
     *  数组作为函数参数或赋值给指针时会发生隐式转换：数组名（在没有衰减为指针的上下文中）并不代表数组本身的地址，而是数组首元素的地址。
     *  因此，name_li 中的char 指针，都指向字符串的第一个元素，直接输出该指针，输出结果是数组，而通过*去获取该指针对应的值，则为数组第一个元素。
     */
    string nn = "joker";
    char *name_li[] =  {
        "1hello1",
        "2hello2",
        "3hello3",
        "4hello4",
    };
    for (char* name: name_li) {
        cout << "name is " << *name << std::endl;
    }
    for (char* name: name_li) {
        cout << "name is " << name << std::endl;
    }
    //
    int arr1[] = {1, 2, 3, 4};
    int arr2[] = {100,200,300,400};
    //  int *num_li[] = {{1, 2, 3, 4}, {100,200,300,400}};
    int *num_li[] = {arr1, arr2};
    int *num_li2[] = {
        new int[3]{1,2,3},
        new int[3]{100,200,300},
    };

    for (int* item: num_li2) {
        cout << "item is " << item << std::endl;
        cout << "item is " << *item << std::endl;
    }

}

void ptr_ptr() {
    int num = 100;
    int * num_pt = &num;
    int ** num_pt_pt = &num_pt;


    cout << "num_pt is " << num_pt << std::endl;
    cout << "num_pt_pt is " << num_pt_pt << std::endl;

    cout << "num is " << *num_pt << std::endl;
    cout << "num is " << **num_pt_pt << std::endl;

}

void ptr_fun( long *x) {
    *x = time(nullptr);

}
void check_ptr_fun() {
    long c_time ;
    ptr_fun(&c_time);
    cout << "c_time is " << c_time << std::endl;
}

double ptr_fun2( int *num_li,int count) {
    int sum =0;
    double avg ;
    for (int i =0;i<count; i++) {
        // 方式一 指针按照数组的方式获取数组中元素
        sum += num_li[i];
        // 方式二 按照指针自增的方式获取数组中元素
        // sum += *num_li;
        // num_li++;
    };
    avg = sum/count;
    return avg;

}

void check_ptr_fun2() {
    int num_li[] = {1,2,3,4,5};
    double avg;
    avg = ptr_fun2(num_li,5);

    cout << "avg is " << avg << std::endl;
}


long* ptr_fun3() {
    int count = 10;
    static long array_ptr[10]; // 数组的数量值必须是编译时常量，而此处为运行时常量
    // static long *array_ptr = new long[count];
    // static vector<long> array_ptr;

    srand( unsigned(time(nullptr)) );
    for (int i=0;i<count;i ++) {
        array_ptr[i] = rand();
    }
    return array_ptr;
}


void check_ptr_fun3() {
    long* array_ptr = ptr_fun3();
    cout << "array_ptr is " << array_ptr << std::endl;
    for (int i = 0; i < 10; i++) {
        // cout << array_ptr[i] << endl;
        cout << *array_ptr++ << endl;
    }

}


vector<long> ptr_fun4() {
    int count = 10;

    static vector<long> array_ptr;
    srand( unsigned(time(nullptr)) );
    for (int i=0;i<count;i ++) {
        long temp = rand();
        array_ptr.push_back(temp);
        cout << "array_ptr is " << temp << endl;
    }
    return array_ptr;
}


void check_ptr_fun4() {
    vector<long> array_ptr = ptr_fun4();

    for (int i = 0; i < 10; i++) {
        // cout << array_ptr[i] << endl;
        cout << array_ptr[i] << endl;
    }

}

void test_ptrppp() {
    int a = 100;
    int* ptr = &a;
    int** ptr_ptr = &ptr;
    int*** ptr_ptr_ptr = &ptr_ptr;
    cout << "size = " << sizeof a << endl;
    cout << "size = " << sizeof ptr << endl;
    cout << "size = " << sizeof ptr_ptr << endl;
    cout << "size = " << sizeof ptr_ptr_ptr << endl;

    cout << "size = " << sizeof *ptr << endl;
    cout << "size = " << sizeof **ptr_ptr << endl;
    cout << "size = " << sizeof ***ptr_ptr_ptr << endl;

    cout << "size = " <<  *ptr << endl;
    cout << "size = " <<  **ptr_ptr << endl;
    cout << "size = " <<  ***ptr_ptr_ptr << endl;

    cout << "size = " <<  **ptr_ptr_ptr << endl;
}


int& test_yinyong_fun() {
    static int a = 5;
    return a;
}

void test_yinyong() {
    int& res = test_yinyong_fun();
    cout << "res is " << res << endl;
    res = 10; // 修改静态变量的值
    cout << "res is " << res << endl;
    test_yinyong_fun();
    cout << "res is " << res << endl;
}


void test_time() {
    time_t  tm_sec = time(nullptr);
    cout << "time is " << tm_sec << endl;


    tm *tt = localtime(&tm_sec);
    cout << "localtime is " << tt->tm_year << endl;
    cout << "localtime is " << tt->tm_mon << endl;
    // cout << "localtime is " << tt->tm_mday << endl;
    // cout << "localtime is " << tt->tm_hour << endl;
    // cout << "localtime is " << tt->tm_min << endl;
    // cout << "localtime is " << tt->tm_sec << endl;
}
void test_cin() {
    char name[50];
    int nums[50];
    cout << "name is "  << endl;
    cin>> name;
    cout << "name is " << name << endl;
    char err_info[] = "error info";

    cerr << err_info << endl;
}

void test_struct() {
    struct mobile {
        string name;
        string country;
        int price;
        mobile(string _name,string _country,int _price):name(_name),country(_country),price(_price) {

        }
        void showinfo() {
            cout << "name is " << name << endl;
            cout << "name is " << country << endl;
            cout << "name is " << price << endl;
        }
    };

    mobile m1 ("m1","c",100);
    mobile m2 ("m2","u",200);


    cout << m1.name << endl;
    cout << m1.country << endl;
    cout << m1.price << endl;

    cout << m2.name << endl;
    cout << m2.country << endl;
    cout << m2.price << endl;

    struct mobile* m_ptr;
    m_ptr = &m1;
    cout << m_ptr->name << endl;
    cout << m_ptr->country << endl;
    cout << m_ptr->price << endl;

    m_ptr->showinfo();
    cout << sizeof m1 <<endl;

}

void test_vector() {
    vector<int> vec(5,10);
    for (int value: vec) {
        cout << "value is " << value << endl;
    }

    for (auto value= vec.begin(); value != vec.end(); value++) {
        cout << *value << endl;
    }

}

void test_map() {
    map<string, string> map1;
    for (int i =0; i < 10; i++) {
        map1[to_string(i)] = to_string(i*i);
    }
    for (pair<const string, string> k:map1) {
        cout << k.first << " " << k.second << endl;
    }

    unordered_map<string, string> map2;
    for (int i =0; i < 10; i++) {
        map2[to_string(i)] = to_string(i*i*i);
    }
    for (pair<const string, string> k:map2) {
        cout << k.first << " " << k.second << endl;
    }
    cout << map1.size() << "--------------"<< endl;
    set<string> set1;
    set1.insert(to_string(1));
    set1.insert(to_string(2));
    set1.insert(to_string(2));
    for (string value : set1) {
        cout << value << endl;
    }


}

int main_main() {
    // count = 5;
    // write_extern();
    // test_thread_local();

    // test_sm();
    // test_cal();
    // test_sizeof();

    // int res = max(10,232);
    // gen_random();
    // test_vector_thread();
    // test_vector_thread2();
    // test_str();

    // testptr();

    // test_array_ptr();
    // ptr_ptr();
    // check_ptr_fun();
    // check_ptr_fun2();

    // check_ptr_fun3();
    // check_ptr_fun4();
    // test_ptrppp();
    // test_yinyong();
    // test_time();

    // test_cin();

    // test_struct();
    // test_vector();
    test_map();
}

